--[[
  Animation Functions
  
  Copyright (c) 2007-2008 Brett Lajzer
  
  See LICENSE for license information.

--]]

--creates a closure that returns which frame the animation is on
--  time is in milliseconds
--  automatically updates when called
--  optional argument to closure will re-initialize the animation at frame 0 and clear the time
--  the second return value is whether the animation is still playing or not
function create_animation_iterator(frames, time, loops)
  local num_frames, c_frame, time_per, c_time, p_time, c_loop, max_loops
  num_frames = frames
  c_frame = 0
  time_per = time
  max_loops = loops or -1
  c_loop = 0
  c_time = -1
  p_time = 0
  
  return function(reinit)
    if reinit ~= nil then c_time = -1 end
    if c_time == -1 then
      p_time = get_ticks()
      c_time = 0
      c_frame = 0
      c_loop = 0
      return 0, true
    end
    
    --adjust for current frame
    c_time = c_time + (get_ticks() - p_time)
    p_time = get_ticks()
    if c_time / time_per > 1 then
      c_frame = c_frame + math.floor(c_time / time_per)
      c_time = c_time % time_per
    end

    --adjust for current loop
    if c_frame >= num_frames then
      c_loop = c_loop + math.floor(c_frame / num_frames)
      c_frame = c_frame % num_frames
    end
    
    --return result
    if max_loops == -1 then
      return c_frame, true
    elseif c_loop >= max_loops then
      return c_frame, false
    else
      return c_frame, true
    end
  end
end



--Creates a relative (delta-based) linear interpolation closure
-- 'val1' is starting value
-- 'val2' is ending value
-- 'time' is length in milliseconds (or number of discrete steps)
--
-- closure gets passed a delta value and returns the current LERPed value
-- second argument of closure is whether or not to reinit it
function create_relative_lerp(time, val1, val2)
  local length, bval, eval, c_time
  length = time 
  bval = val1
  eval = val2
  c_time = 0
  
  return function(dt, reinit)
    c_time = c_time + dt
    
    if reinit ~= nil then c_time = 0 end
    
    if c_time >= length then return eval end
    
    local percent = c_time / length
    
    return (bval * (1.0 - percent)) + (eval * (percent)) 
  end
end


--Creates an absolute linear interpolation closure
-- 'val1' is starting value
-- 'val2' is ending value
-- 'time' is length in milliseconds (or number of discrete steps)
--
-- closure gets passed a value and returns the appropriate LERPed value
function create_absolute_lerp(time, val1, val2)
  local length, bval, eval, c_time
  length = time 
  bval = val1
  eval = val2
  
  return function(val)
    if val >= length then return eval end
    
    local percent = val / length
    
    return (bval * (1.0 - percent)) + (eval * (percent))
  end
end
